package code.bigmama.views;

import java.io.IOException;

import android.content.Context;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnKeyListener;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, AutoFocusCallback, OnKeyListener, Camera.ShutterCallback
{
	public static final String	DEBUG_TAG			= "CameraView";

	SurfaceHolder				mSurfaceHolder;
	Camera						mCameraDevice;

	private boolean				mAutoFocused		= false;
	private boolean				mTakenPicture		= false;

	private byte[]				mJpgByte			= null;

	public CameraView(Context context)
	{
		super(context);
		Log.d(DEBUG_TAG, "CameraView(Context context)");
		setSurfaceHolder();
	}

	public CameraView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		Log.d(DEBUG_TAG, "CameraView(Context context, AttributeSet attrs)");
		setSurfaceHolder();
	}

	public CameraView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		Log.d(DEBUG_TAG, "CameraView(Context context, AttributeSet attrs, int defStyle)");
		setSurfaceHolder();
	}

	private void setSurfaceHolder()
	{
		mSurfaceHolder = getHolder();
		mSurfaceHolder.addCallback(this);
		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	public void autofocus()
	{
		if (mAutoFocused == false)
		{
			mCameraDevice.autoFocus(this);
			mAutoFocused = true;
		}
	}
	
	public boolean isTaken()
	{
		return mTakenPicture;
	}
	
	public byte[] getByte()
	{
		return mJpgByte;
	}

	public void takePicture()
	{
		if (mAutoFocused == false)
		{
			mCameraDevice.autoFocus(this);
			mAutoFocused = true;
		}

		if (mTakenPicture == false)
		{
			mCameraDevice.takePicture(this, new RAW(), new JPG());
			mCameraDevice.stopPreview();
			mTakenPicture = true;
		}
	}

	public void resetAutoFocus()
	{
		mAutoFocused = false;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
	{
		Log.d(DEBUG_TAG, "surfaceChanged()");
		
		Camera.Parameters parameters = mCameraDevice.getParameters();
		parameters.setPreviewSize(width, height);
		mCameraDevice.setParameters(parameters);
		
		mCameraDevice.startPreview();
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		Log.d(DEBUG_TAG, "surfaceCreated()");
	
		mCameraDevice = Camera.open();

		try
		{
			mCameraDevice.setPreviewDisplay(holder);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			Log.d(DEBUG_TAG, e.getMessage());

			mCameraDevice.release();
			mCameraDevice = null;
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		Log.d(DEBUG_TAG, "surfaceDestroyed()");
		
		mCameraDevice.stopPreview();
		mCameraDevice.release();
		mCameraDevice = null;

	}

	@Override
	public void onAutoFocus(boolean success, Camera camera)
	{
		if (success == true)
		{
			Log.d(DEBUG_TAG, "camera is now focused automatically...");
		}
	}

	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event)
	{
		Log.d(DEBUG_TAG, String.format("pressed key : %d", keyCode));

		return true;
	}

	@Override
	public void onShutter()
	{
		Log.d(CameraView.DEBUG_TAG, "Shutter()");
	}

	class JPG implements Camera.PictureCallback
	{
		@Override
		public void onPictureTaken(byte[] data, Camera camera)
		{
			Log.d(CameraView.DEBUG_TAG, "jpg Picture Taken()");

			mJpgByte = data;
		}
	}

	class RAW implements Camera.PictureCallback
	{
		private byte[] mRawByte;

		@Override
		public void onPictureTaken(byte[] data, Camera camera)
		{
			Log.d(CameraView.DEBUG_TAG, "raw PictureTaken()");

			mRawByte = data;
		}
	}

}
